package com.central.dataManage.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.central.common.annotation.LoginUser;
import com.central.common.constant.CommonConstant;
import com.central.common.model.DatasourceInfo;
import com.central.common.model.Result;
import com.central.common.model.SysUser;
import com.central.common.model.TableInfo;
import com.central.common.utils.UserRoleUtil;
import com.central.dataManage.model.*;
import com.central.dataManage.service.IDatabaseService;
import com.central.dataManage.service.IDatasourceService;
import com.central.dataManage.service.ITableService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;

/**
 * @author Tindy
 * @date 2021/6/24
 * @describe
 */
@Slf4j
@RestController
@Api(tags = "数据目录api")
@RequestMapping(value = "/dataCatalog")
public class DataCatalogController {

    @Autowired
    private IDatasourceService datasourceService;
    @Autowired
    private IDatabaseService databaseService;
    @Autowired
    private ITableService tableService;

    @ApiOperation(value = "获取公共数据目录数据源层级目录")
    @Cacheable(value = "datasourceList")
    @GetMapping("/publicDataCatDatasource")
    public List<DatasourceInfo> publicDataCatDatasource(@ApiIgnore @LoginUser SysUser user) {
        return datasourceService.list(new QueryWrapper<DatasourceInfo>().select("id","name","description","datasource_type"));
    }

    @ApiOperation(value = "获取公共数据目录数据库层级目录")
    @Cacheable(value = {"databaseList"},key ="#datasourceId")
    @GetMapping("/publicDataCatDatabase")
    public List<DatabaseInfo> publicDataCatDatabase(@ApiIgnore @LoginUser SysUser user, Long datasourceId) {
        return databaseService.list(new QueryWrapper<DatabaseInfo>().eq("datasource_id",datasourceId).notLike("db_name",CommonConstant.USER_DB_PREFIX+"%"));
    }

    @ApiOperation(value = "获取公共数据目录数据表层级目录")
    @Cacheable(value = {"tableList"},key ="#databaseId")
    @GetMapping("/publicDataCatTable")
    public List<Map<String,Object>> publicDataCatTable(@ApiIgnore @LoginUser SysUser user, Long databaseId) {
        return tableService.listMaps(new QueryWrapper<TableInfo>().eq("database_id",databaseId).select("id","table_name"));
    }

    @ApiOperation(value = "获取用户数据目录数据库层级目录")
    @GetMapping("/userDataCatDatabase")
    public DatabaseInfo userDataCatDatabase(@ApiIgnore @LoginUser SysUser user) {
        return databaseService.getUserDb(user);
    }


    @ApiOperation(value = "获取项目数据目录数据库层级目录")
    @GetMapping("/proDataCatDatabase")
    public DatabaseInfo proDataCatDatabase(@ApiIgnore @LoginUser SysUser user) {
        return databaseService.getProDb(user);
    }

    @ApiOperation(value = "创建库")
    @CacheEvict(value = "databaseList",key="#datasourceId")
    @GetMapping("/createDatabase")
    public Result createDatabase(@ApiIgnore @LoginUser SysUser user, Long datasourceId,String dbName,String reason) {
        //全局数据管理员直接创建
        if(UserRoleUtil.checkGloDataAdmin(user.getRoles())){
            return databaseService.createDatabase(datasourceId,dbName,reason);
        }
        //TODO 其他成员，走流程申请
        return Result.succeed("申请成功，待审核");
    }

    @ApiOperation(value = "删除库")
    @CacheEvict(value = "tableList",key="#databaseId")
    @GetMapping("/dropDatabase")
    public Result dropDatabase(@ApiIgnore @LoginUser SysUser user,Long databaseId,String reason) {
        //全局数据管理员直接删除
        if(UserRoleUtil.checkGloDataAdmin(user.getRoles())){
            return databaseService.dropDatabase(databaseId,reason);
        }
        //TODO 其他成员，走流程申请
        return Result.succeed("申请成功，待审核");

    }

    @ApiOperation(value = "同步库")
    @CacheEvict(value = "tableList",key="#databaseId")
    @GetMapping("/synchDatabase")
    public Result synchDatabase(Long databaseId) throws SQLException {
        Boolean flag= databaseService.synchDatabase(databaseId);
        if (flag) {
            return Result.succeed("同步成功");
        } else {
            return Result.failed("同步失败");
        }
    }

    @ApiOperation(value = "创建表")
    @CacheEvict(value = "tableList",key="#createTableEntity.databaseId")
    @PostMapping("/createTable")
    public Result createTable(@ApiIgnore @LoginUser SysUser user, @RequestBody CreateTableEntity createTableEntity) {
        //全局数据管理员直接创建
        if(UserRoleUtil.checkGloDataAdmin(user.getRoles())){
            return tableService.createTable(createTableEntity);
        }
        //TODO 其他成员，走流程申请
        return Result.succeed("申请成功，待审核");

    }

    @ApiOperation(value = "创建项目库表")
    @CacheEvict(value = "tableList",key="#createTableEntity.databaseId")
    @PostMapping("/createProTable")
    public Result createProTable(@ApiIgnore @LoginUser SysUser user, @RequestBody CreateTableEntity createTableEntity) {
        DatabaseInfo databaseInfo = proDataCatDatabase(user);
        if(databaseInfo!=null && databaseInfo.getId()==createTableEntity.getDatabaseId()){
            //项目数据管理员直接创建
            if(UserRoleUtil.checkProDataAdmin(user.getProRoles())){
                return tableService.createTable(createTableEntity);
            }
            //TODO 其他成员，走流程申请
            return Result.succeed("申请成功，待审核");
        }else {
            return Result.failed("当前用户与项目库不匹配");
        }
    }
    @ApiOperation(value = "创建用户库表")
    @CacheEvict(value = "tableList",key="#createTableEntity.databaseId")
    @PostMapping("/createUserTable")
    public Result createUserTable(@ApiIgnore @LoginUser SysUser user, @RequestBody CreateTableEntity createTableEntity) {
        DatabaseInfo databaseInfo = userDataCatDatabase(user);
        if(databaseInfo!=null && databaseInfo.getId()==createTableEntity.getDatabaseId()){
            return tableService.createTable(createTableEntity);
        }else {
            return Result.failed("当前用户与用户库不匹配");
        }
    }

    @ApiOperation(value = "删除表")
    @GetMapping("/dropTable")
    public Result dropTable(@ApiIgnore @LoginUser SysUser user, Long tableId,String reason) {
        //全局数据管理员直接删除
        if(UserRoleUtil.checkGloDataAdmin(user.getRoles())){
            return tableService.dropTable(tableId,reason);
        }
        //TODO 其他成员，走流程申请
        return Result.succeed("申请成功，待审核");

    }

    @ApiOperation(value = "删除项目库表")
    @GetMapping("/dropProTable")
    public Result dropProTable(@ApiIgnore @LoginUser SysUser user, Long tableId,String reason) {
        DatabaseInfo databaseInfo = proDataCatDatabase(user);
        TableInfo tableInfo = tableService.getById(tableId);
        if(databaseInfo!=null && tableInfo!=null && databaseInfo.getId()==tableInfo.getDatabaseId()){
            //项目数据管理员直接删除
            if(UserRoleUtil.checkProDataAdmin(user.getProRoles())){
                return tableService.dropTable(tableId,reason);
            }
            //TODO 其他成员，走流程申请
            return Result.succeed("申请成功，待审核");
        }else {
            return Result.failed("当前用户项目与项目库不匹配");
        }
    }
    @ApiOperation(value = "删除用户库表")
    @GetMapping("/dropUserTable")
    public Result dropTable(@ApiIgnore @LoginUser SysUser user, Long tableId) {
        DatabaseInfo databaseInfo = userDataCatDatabase(user);
        TableInfo tableInfo = tableService.getById(tableId);
        if(databaseInfo!=null && tableInfo!=null && databaseInfo.getId()==tableInfo.getDatabaseId()){
            return tableService.dropTable(tableId,"");
        }else {
            return Result.failed("当前用户与用户库不匹配");
        }
    }


    @ApiOperation(value = "同步表")
    @GetMapping("/synchTable")
    public Result synchTable(Long tableId) throws SQLException {
        Boolean flag=tableService.synchTable(tableId);
        if (flag) {
            return Result.succeed("同步成功");
        } else {
            return Result.failed("同步失败");
        }
    }

    @ApiOperation(value = "修改表")
    @PostMapping("/modifyTable")
    public Result modifyTable(@ApiIgnore @LoginUser SysUser user, @RequestBody ModifyTableEntity modifyTableEntity) throws ExecutionException, InterruptedException {
        //全局数据管理员直接创建
        if(UserRoleUtil.checkGloDataAdmin(user.getRoles())){
            return tableService.modifyTable(modifyTableEntity);
        }
        //TODO 其他成员，走流程申请
        return Result.succeed("申请成功，待审核");
    }

    @ApiOperation(value = "修改项目库表")
    @PostMapping("/modifyProTable")
    public Result modifyProTable(@ApiIgnore @LoginUser SysUser user, @RequestBody ModifyTableEntity modifyTableEntity) throws ExecutionException, InterruptedException {
        DatabaseInfo databaseInfo = proDataCatDatabase(user);
        TableInfo tableInfo = tableService.getById(modifyTableEntity.getTableId());
        if(databaseInfo!=null && databaseInfo.getId()==tableInfo.getDatabaseId()){
            //项目数据管理员直接创建
            if(UserRoleUtil.checkProDataAdmin(user.getProRoles())){
                return tableService.modifyTable(modifyTableEntity);
            }
            //TODO 其他成员，走流程申请
            return Result.succeed("申请成功，待审核");
        }else {
            return Result.failed("当前用户与项目库不匹配");
        }
    }

    @ApiOperation(value = "修改用户库表")
    @PostMapping("/modifyUserTable")
    public Result modifyUserTable(@ApiIgnore @LoginUser SysUser user, @RequestBody ModifyTableEntity modifyTableEntity) throws ExecutionException, InterruptedException {
        DatabaseInfo databaseInfo = userDataCatDatabase(user);
        TableInfo tableInfo = tableService.getById(modifyTableEntity.getTableId());
        if(databaseInfo!=null && databaseInfo.getId()==tableInfo.getDatabaseId()){
            return tableService.modifyTable(modifyTableEntity);
        }else {
            return Result.failed("当前用户与用户库不匹配");
        }
    }
}
